package net.oschina.arvin.sqlbuilder.definition;

import net.oschina.arvin.sqlbuilder.WhereBuilder;
import net.oschina.arvin.sqlbuilder.enums.CompareType;
import net.oschina.arvin.sqlbuilder.utils.AssertUtil;

import java.lang.reflect.Field;

/**
 * Map 属性，查询
 *
 * @author Arvin
 * @time 2017/11/17 20:15
 */
public abstract class AbstractGeneralConditionItem implements ConditionItem {

    /** 对应模型列定义 */
    private final ColumnDefinition modelColumnDefinition;

    /** 比较类型 */
    private final CompareType compareType;

    public AbstractGeneralConditionItem(ColumnDefinition modelColumnDefinition, CompareType compareType) {
        AssertUtil.assertNotNull(modelColumnDefinition, "模型列定义不能为null");

        this.modelColumnDefinition = modelColumnDefinition;
        this.compareType = null == compareType ? CompareType.EQUAL : compareType;
    }

    @Override
    public Field getQueryConditionField() {
        return getModelColumnDefinition().getField();
    }

    public ColumnDefinition getModelColumnDefinition() {
        return modelColumnDefinition;
    }

    public CompareType getCompareType() {
        return compareType;
    }

    /**
     * 返回是否进行了追加
     *
     * @param whereBuilder Where子句构造器
     * @return 返回是否进行了追加
     */
    @Override
    public boolean appendToWhereBuilder(Object queryCondition, WhereBuilder whereBuilder, CompareType compareType) {
        AssertUtil.assertNotNull(whereBuilder, "WhereBuilder 不能为空！");

        compareType = null == compareType ? getCompareType() : compareType;

        AssertUtil.assertTrue(null != compareType && isSupportCompareType(compareType), getFieldStringInfo() + " 不支持比较类型 [" + compareType + "]！");

        return customAppendToWhereBuilder(queryCondition, whereBuilder, compareType);
    }

    protected String getFieldStringInfo() {
        return "[" + this.getModelColumnDefinition().getFieldName() + "]";
    }

    /**
     * 验证是否是支持的查询类型
     *
     * @param compareType 要验证的查询类型
     */
    protected abstract boolean isSupportCompareType(CompareType compareType);

    /**
     * 自定义 append 策略
     */
    protected abstract boolean customAppendToWhereBuilder(Object queryCondition, WhereBuilder whereBuilder, CompareType compareType);

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        AbstractGeneralConditionItem that = (AbstractGeneralConditionItem) o;

        return modelColumnDefinition.equals(that.modelColumnDefinition);

    }

    @Override
    public int hashCode() {
        return modelColumnDefinition.hashCode();
    }
}
